package com.ucar.train.service.xumingzhi.Process;




import com.ucar.train.service.xumingzhi.ResultUtil.Result;
import com.ucar.train.service.xumingzhi.ResultUtil.ResultEnum;
import com.ucar.train.service.xumingzhi.ResultUtil.ResultUtil;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * Desciption:
 *
 * @Author: XuMingZhi.
 * Creation time: 2019/8/22 8:36:00.
 * © Copyright 2013-2019, UCar.
 */
public abstract class ProcessTemplate {
    private ProcessTemplate nextProcessTemplate;
    private ProcessTemplate preProcessTemplate;
    private int timeOutCount = 0;//超时次数
    private int badRequestCount = 0;//请求错误次数
    private Boolean isPre=false;

    public ProcessTemplate() {
    }

    public ProcessTemplate getNextProcessTemplate() {
        return nextProcessTemplate;
    }

    public void setNextProcessTemplate(ProcessTemplate nextProcessTemplate) {
        this.nextProcessTemplate = nextProcessTemplate;
    }

    public ProcessTemplate getPreProcessTemplate() {
        return preProcessTemplate;
    }

    public void setPreProcessTemplate(ProcessTemplate preProcessTemplate) {
        this.preProcessTemplate = preProcessTemplate;
    }

    // 处理请求传递，注意final，子类不可重写
    public final Result handleMessage()  {
        //todo 简化过多的if else
        ProcessTemplate temp = this;
        while (temp != null) {
            Result result = null;
            try {
                try {
                    result = temp.maintain();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (ResultEnum.SUCCESS.getCode().equals(result.getCode())) {//成功
                System.out.println(result);
                temp = temp.nextProcessTemplate;
                timeOutCount=0;
                if(!isPre){
                    badRequestCount=0;
                }
            } else if (ResultEnum.REQUEST_TIMEOUT.getCode().equals(result.getCode())) {//响应超时，重启
                System.out.println(result);
                if (timeOutCount > 1) {
                    timeOutCount = 0;
                    return ResultUtil.BADGATEWAY("进程响应无效，终止保养");
                } else {
                    timeOutCount++;
                }
            } else if (ResultEnum.BAD_REQUEST.getCode().equals(result.getCode())) {//请求错误，从上一个开始
                System.out.println(result);
                if (badRequestCount > 1) {
                    badRequestCount = 0;
                    return ResultUtil.GONE("请求错误，终止保养");
                } else {
                    if (temp.getPreProcessTemplate() != null) {
                        temp = temp.preProcessTemplate;
                        badRequestCount++;
                        isPre=true;
                    } else {
                        badRequestCount++;
                        isPre=true;
                    }
                }
            }
        }
        return ResultUtil.SUCCESS("保养成功");
    }


    // 抽象方法，子类实现
    public abstract Result maintain() throws ExecutionException, InterruptedException, TimeoutException;
    /**
     * 1.线程执行时间太长或无响应，返回 REQUEST_TIMEOUT进行重连
     * 2.请求错误，返回BAD_REQUEST，从上一个进程开始。
     * 3.保存一下进度
     */

}
